package com.qf.chinatelcom.apiinterface.service.impl;

import com.qf.chinatelcom.apiinterface.feign.CacheService;
import com.qf.chinatelcom.apiinterface.pojo.MessageBody;
import com.qf.chinatelcom.apiinterface.service.CheckSmsService;
import com.qf.chinatelcom.apiinterface.service.SmsMQService;
import com.qf.chinatelcom.apiinterface.utils.PhoneFormatCheckUtil;
import com.qianfeng.smsplatform.common.constants.CacheConstants;
import com.qianfeng.smsplatform.common.constants.InterfaceExceptionDict;
import com.qianfeng.smsplatform.common.exceptions.MyBaseException;
import com.qianfeng.smsplatform.common.model.Standard_Submit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.ObjectUtils;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class CheckSmsServiceImpl implements CheckSmsService {
    private SmsMQService smsMQService;

    @Autowired
    public void setSmsMQService(SmsMQService smsMQService) {
        this.smsMQService = smsMQService;
    }
    private CacheService cacheService;

    @Autowired
    public void setCacheService(CacheService cacheService) {
        this.cacheService = cacheService;
    }

    @Override
    public List<String> checkSms(MessageBody body, String ip) {
        //检查内容是否和手机号的数量匹配
        String[] contents = body.getContents();
        if(contents==null&&contents.length==0){
            //没有传递短信内容，需要抛异常，直接返回
            System.out.println("没有收到短信内容");
            throw new MyBaseException("没有收到短信内容", InterfaceExceptionDict.RETURN_STATUS_MESSAGE_ERROR);

        }
        //检查手机号
        String mobiles = body.getMobiles();//获取到所有的手机号，手机号可能存在多个
        if(ObjectUtils.isEmpty(mobiles)){
            //可能没有传递手机号,这个地方万一传递为空呢,这地方就是判断一下
            throw new MyBaseException("没有传递手机号", InterfaceExceptionDict.RETURN_STATUS_MOBILE_ERROR);
        }
        String[] split = mobiles.split(",");//将手机号用，分隔开
        if (contents.length!=1&&contents.length!=split.length){
            //需要传递的内容与手机号的数量不匹配,需要直接抛异常
            System.err.println("手机号需要传递的数量与手机号的数量不匹配");
            throw new MyBaseException("手机号需要传递的数量与手机号的数量不匹配", InterfaceExceptionDict.RETURN_STATUS_MESSAGE_PHONE_NOT_MATCH);
        }
        //检查手机号是不是合法的手机号
        List<String> okList = new ArrayList<>();//存放合法的手机号
        List<String> noList = new ArrayList<>();//存放不合法的手机号
        List<String> messageList = new ArrayList<>();//存放内容



        int length = contents.length;//短信内容的长度
        for (int i = 0; i < split.length; i++) {
            String s = split[i];
            boolean phoneLegal = PhoneFormatCheckUtil.isChinaPhoneLegal(s);
            if(phoneLegal){
                okList.add(s);//存入合法的手机号
                //如果上边有非法的手机号，说明我们的内容是跟它的长度是一一对应的，所以我们需要进行删掉对应的短信内容
                //但是我们并不知到集合的下标，及时指导下表也不可贸然删除，因为删除后集合时会移动的，可能你想删除的是1，3结果删除了1，4
                if(length==1){
                    messageList.add(contents[0]);
                }else{
                    messageList.add(contents[i]);//将对应位置上合法手机号的内容保存下来
                }
            }else{
                noList.add(s);//存入不合法的手机号
            }
        }
        //检查用户名和密码
        //怎末校验用户名和密码，密码是密文存储的，可是我们传输过来的却是明文，该如何进行转换
        Map hmget = cacheService.hmget(CacheConstants.CACHE_PREFIX_CLIENT + body.getUsercode());
        if(hmget.size()==0||hmget==null){
            //这判断的是用户名是否存在，如果不存在就直接返回
            throw new MyBaseException("用户名或密码不对", InterfaceExceptionDict.RETURN_STATUS_CLIENTID_PWD_ERROR);
        }
        //我们需要把用户的密码获取到，然后进行密文转换，比如可以使用 MD5  SHA等方式
        //熵增,信息差  100G  薛定谔的猫,麦克斯韦妖 香农理论
        //DES AES 对称加密,加密和解密密码一样
        //RSA DSA 非对称加密，加密和解密方法不一样，有公钥以及私钥以及ssh证书，以及大素数碰撞
        //按照用户名查询信息，查询到密码，那麽我们就能把用户信息放到缓存中
        //以某个内容标识，用户的表示可以是id也可以是用户名
        //用户的表示会有很多，所以我们存放的是存hash
        String pwd = (String) hmget.get("pwd");//去缓存中查找这个用户的密码
        String password = body.getPassword();//获取用户传递过来的密码
        String md5password = DigestUtils.md5DigestAsHex(password.getBytes(StandardCharsets.UTF_8));
        if(!md5password.equalsIgnoreCase(pwd)){
            //说明查找出来比对的密码不对，需要直接返回
            throw new MyBaseException("用户名或密码不对",  InterfaceExceptionDict.RETURN_STATUS_CLIENTID_PWD_ERROR);
        }
        //检查这个用户是不是在白名单中
        //获取到允许的ip列表
        String ipaddress = (String) hmget.get("ipaddress");
        //判断当前存在的IP在不在列表中
        if(!ipaddress.contains(ip)){
            //如果不存在据直接返回
            throw new MyBaseException("ip不在列表中", InterfaceExceptionDict.RETURN_STATUS_IP_ERROR);
        }
        //如果一切都没有问题
        List<Standard_Submit> submitList = new ArrayList<>();
        //发送出去，通过mq发送出去
        for (int i = 0; i < okList.size(); i++) {
            String s = okList.get(i);//获取到每一个手机号
            String msg = messageList.get(i);//获取到每个内容
            Standard_Submit submit = new Standard_Submit();//创建对象
            submit.setClientID(body.getUsercode());//将所有的用户名存入
            submit.setDestMobile(s);//将所有的手机号存入
            submit.setMessageContent(msg);//将所有的内容存入
            submit.setSendTime(new Date());//获取到当前时间，并把当前时间存入
            submit.setSrcSequenceId(body.getSrcSequenceId());//获取到他们的唯一id
            submitList.add(submit);//将弄好的对象存到集合中
        }
        //将所有数据返回发送
        smsMQService.sendSms2Mq(submitList);
        //将不合法的手机号返回
        return noList;
    }
}
